using System;
using System.Collections;
using System.Collections.Generic;


namespace LightCAD.Three
{
    public class CircleGeometry : BufferGeometry
    {
        public class Parameters
        {
            public double radius;
            public int segments;
            public double thetaStart;
            public double thetaLength;
        }
        #region Properties

        public Parameters parameters;

        #endregion

        #region constructor
        public CircleGeometry(double radius = 1, int segments = 32, double thetaStart = 0, double thetaLength = Math.PI * 2)
        {
            this.type = "CircleGeometry";
            this.parameters = new Parameters()
            {
                radius = radius,
                segments = segments,
                thetaStart = thetaStart,
                thetaLength = thetaLength
            };
            segments = JMath.max(3, segments);
            // buffers
            var indices = new JsArr<int>();
            var vertices = new JsArr<double>();
            var normals = new JsArr<double>();
            var uvs = new JsArr<double>();
            // helper variables
            var vertex = new Vector3();
            var uv = new Vector2();
            // center point
            vertices.push(0, 0, 0);
            normals.push(0, 0, 1);
            uvs.push(0.5, 0.5);
            for (int s = 0, i = 3; s <= segments; s++, i += 3)
            {
                var segment = thetaStart + s / (double)segments * thetaLength;
                // vertex
                vertex.x = radius * JMath.cos(segment);
                vertex.y = radius * JMath.sin(segment);
                vertices.push(vertex.x, vertex.y, vertex.z);
                // normal
                normals.push(0, 0, 1);
                // uvs
                uv.x = (vertices[i] / radius + 1) / 2;
                uv.y = (vertices[i + 1] / radius + 1) / 2;
                uvs.push(uv.x, uv.y);
            }
            // indices
            for (int i = 1; i <= segments; i++)
            {
                indices.push(i, i + 1, 0);
            }
            // build geometry
            this.setIndex(indices.ToArray());
            this.setAttribute("position", new Float32BufferAttribute(vertices.ToArray(), 3));
            this.setAttribute("normal", new Float32BufferAttribute(normals.ToArray(), 3));
            this.setAttribute("uv", new Float32BufferAttribute(uvs.ToArray(), 2));
        }
        #endregion


        #region methods
        public CircleGeometry copy(CircleGeometry source)
        {
            base.copy(source);
            this.parameters = new Parameters()
            {
                radius = source.parameters.radius,
                segments = source.parameters.segments,
                thetaStart = source.parameters.thetaStart,
                thetaLength = source.parameters.thetaLength,
            };
            return this;
        }

        #endregion
    }
}
